#include <iostream>
#include <sstream>
#include <string>
#include <vector>
#include <Windows.h>
#include "time_mgmt.h"

#define WIN_OS               1
//test1


#define WC_NULL              L'\0'
#define WND_CLASS_NAM_SIZE   100 
#define WND_TITLE_NAM_SIZE   WND_CLASS_NAM_SIZE 
#define OSTREAM_MUTEX        L"ostreamMutex"

#define ARRAY_SIZE(x)       ( sizeof( (x) )/sizeof( *(x ) ) )

using namespace std;

BOOL CALLBACK EnumWndProc(HWND hwnd, __in  LPARAM lParam);

string wcToString(const WCHAR *wInput)
{
    const WORD maxTextSize      = 100;
    CHAR cOutput[maxTextSize+1] = {0}; 
    wcstombs_s(NULL, cOutput, wInput, maxTextSize); 
    if( *cOutput ) 
        return string(cOutput); 

    return " N/A ";
}


string decToHexString(const DWORD dInput)
{
    ostringstream os; 
    os<<hex<<"0x"<<uppercase<<dInput<<nouppercase<<dec; 

    return os.str();
}

wstring charToWc(const CHAR *cInput)
{
    const WORD maxTextSize     = 100;
    WCHAR wOutput[maxTextSize] = {0}; 
    mbstowcs_s(NULL, wOutput, cInput, maxTextSize); 

    return wstring(wOutput);  
}

struct wnd_info {
    wnd_info(): hwnd(0)    { *wClassName = WC_NULL; *wTitle = WC_NULL; }
    wnd_info(HWND wndHwnd) { this->wnd_info::wnd_info(); hwnd = wndHwnd; }
    wnd_info(LPTSTR cname) { this->wnd_info::wnd_info(); if(cname) wcsncpy_s(wClassName, cNameSizeMax, cname, cNameSizeMax); }
    wnd_info(LPCSTR cname) { this->wnd_info::wnd_info(); if(cname) mbstowcs_s(NULL, wClassName, cname, cNameSizeMax); }
    wnd_info(LPTSTR cname, LPTSTR tname)  
                           { this->wnd_info::wnd_info(); if(cname) wcsncpy_s(wClassName, cNameSizeMax, cname, cNameSizeMax); 
                                                         if(tname) wcsncpy_s(wTitle, tNameSizeMax, tname, tNameSizeMax);     }   
    wnd_info(LPCSTR cname, LPCSTR tname)  
                           { this->wnd_info::wnd_info(); if(cname) mbstowcs_s(NULL, wClassName, cname, cNameSizeMax); 
                                                         if(tname) mbstowcs_s(NULL, wTitle, tname, tNameSizeMax);     }       
 
    static const WORD cNameSizeMax = WND_CLASS_NAM_SIZE;
    static const WORD tNameSizeMax = WND_TITLE_NAM_SIZE;
    WCHAR wClassName[cNameSizeMax+1];   
    WCHAR wTitle[tNameSizeMax+1];    
    HWND  hwnd;                           
};

struct wnd_search {
    static const enum mode{ undef= 0, all, };
    wnd_search(): extracted(0), wndData() {}
    wnd_search(mode mod): extracted(0), wndData() { if(mod==all) startSearch(); }
    wnd_search(LPTSTR cname): extracted(0), wndData(cname) { startSearch(); }
    wnd_search(LPCSTR cname): extracted(0), wndData(cname) { startSearch(); }
    wnd_search(LPTSTR cname, LPTSTR tname): extracted(0), wndData(cname, tname) { startSearch(); }
    wnd_search(LPCSTR cname, LPCSTR tname): extracted(0), wndData(cname, tname) { startSearch(); }

    BOOL is_cNameSame(LPTSTR cname) const { if( !wcsncmp(cname, wndData.wClassName, wndData.cNameSizeMax) ) return TRUE; return FALSE; }
    BOOL is_titleSame(LPTSTR tname) const { if( !wcsncmp(tname, wndData.wTitle, wndData.tNameSizeMax) ) return TRUE; return FALSE; }
    void startSearch()              const { EnumWindows( EnumWndProc, (LPARAM)(this) ); }
    DWORD getExtractedSize()        const { return extracted.size(); }

    wnd_info getExtracted()           { const wnd_info first = extracted.front(); extracted.erase(extracted.begin()); return first; }
    void insertMatched(wnd_info wnd)  { extracted.push_back(wnd); };

    wnd_info wndData;
    vector<wnd_info> extracted;
};

class stream {
public:
    static stream &instance() { 
        static stream instance; 
        return instance; 
    }

    ostream &get_os() { ostringstream *os = new ostringstream; ostream_queue.push_back(os); return *os; }

    bool print() {       
        if(ostream_queue.size()) {
            
            if(WaitForSingleObject(sMutex, INFINITE) == WAIT_OBJECT_0) {    
                os<<( *(ostream_queue.front()) ).str(); 
                delete ostream_queue.front();
                ostream_queue.erase( ostream_queue.begin() );

                ReleaseMutex(sMutex);
                return true;
            }     
        }

        return false;
    } 
    

private:
    stream() {}  
    stream(const stream&);
    stream &operator=(const stream&); 
    
    static ostream &os;
    static istream &is;
    static HANDLE sMutex; 
    static vector<ostringstream *> ostream_queue; 
};

vector<ostringstream *> stream::ostream_queue;
HANDLE stream::sMutex = CreateMutex(NULL, FALSE, OSTREAM_MUTEX);
ostream &stream::os = cout;
istream &stream::is = cin;

#define OUTSTREAM     stream::instance().get_os()
#define PRINTOUT      stream::instance().print()



BOOL CALLBACK EnumWndProc(HWND hwnd, __in  LPARAM lParam)
{
    wnd_search *Wnd = reinterpret_cast<wnd_search*>(lParam);
    if( !lParam )
        return FALSE;
                    
    wnd_info currWnd(hwnd);
    GetClassName (hwnd, currWnd.wClassName, WND_CLASS_NAM_SIZE);
    GetWindowText(hwnd, currWnd.wTitle, WND_TITLE_NAM_SIZE);

    if( *Wnd->wndData.wClassName && *Wnd->wndData.wTitle ) {
        if( Wnd->is_cNameSame(currWnd.wClassName) && Wnd->is_titleSame(currWnd.wTitle) )
            Wnd->insertMatched(currWnd);
    }
    else if( *Wnd->wndData.wClassName && Wnd->is_cNameSame(currWnd.wClassName) ) { 
        Wnd->insertMatched(currWnd);
    }
    else if( *Wnd->wndData.wTitle && Wnd->is_titleSame(currWnd.wTitle) ) {
        Wnd->insertMatched(currWnd);
    }
    else if( !(*Wnd->wndData.wClassName) && !(*Wnd->wndData.wTitle) ) {
        Wnd->insertMatched(currWnd);
    }
     
    return TRUE;
}


BOOL closeWindows(wnd_info &wndInput)
{
    BOOL ret_status = EXIT_FAILURE;
    wnd_search new_search;

    if( !(*wndInput.wClassName) && !(*wndInput.wTitle) )
        new_search = wnd_search(wnd_search::all);
    else if( wndInput.hwnd )
        new_search.insertMatched(wndInput);
    else
        new_search = wnd_search(wndInput.wClassName, wndInput.wTitle);    

    if( new_search.getExtractedSize() ) {
        while( new_search.getExtractedSize() ) {
            wnd_info match = new_search.getExtracted();
            SendMessage(match.hwnd, WM_CLOSE, 0, 0); 

            static const WORD isWindowTimeout = 20;
            for(WORD msCount=0; (IsWindow(match.hwnd) && msCount < isWindowTimeout); ++msCount) 
                Sleep(1);

            if( IsWindow(match.hwnd) ) {
                    OUTSTREAM<<"(!)CANNOT close window[hwnd]: "<<wcToString(match.wTitle)
                             <<" | "<<wcToString(match.wClassName)
                             <<" ["<<decToHexString((DWORD)match.hwnd)<<"]"<<endl;
                                            
                    PRINTOUT; 
                    break;                                                        
            }
            else {
                OUTSTREAM<<"Window[hwnd]: "<<wcToString(match.wTitle)
                          <<" | "<<wcToString(match.wClassName)
                          <<" ["<<decToHexString((DWORD)match.hwnd)<<"] closed."<<endl; 
                PRINTOUT;  
            }
        } 

        if( !new_search.getExtractedSize() )
            ret_status = EXIT_SUCCESS;
    } 

    return ret_status;
}

BOOL isKeyDown(WORD key)
{
    static const SHORT filter = (SHORT)(1<<(CHAR_BIT*sizeof(SHORT)-1));

    if(GetAsyncKeyState(key) & filter)
        return TRUE;

    return FALSE;
}


WORD kbchk()  
{  
    for(int i=0x01, k=0x9F; i<k; ++i)  
        if( isKeyDown(i) ) {
            for(int j=0x01; j<k; ++j)  
                if( j != i && isKeyDown(j) )
                    return i|j;
            return i;
        }

    return 0;       
}  


LRESULT CALLBACK LowLevelMouseProc(int code, WPARAM wParam, LPARAM lParam)
{  
    return LPARAM(0);  

    if (code == HC_ACTION)
    {
        const char *msg;
        char msg_buff[128];
        switch (wParam)
        {
            case WM_LBUTTONDOWN: msg = "WM_LBUTTONDOWN"; break;
            case WM_LBUTTONUP: msg = "WM_LBUTTONUP"; break;
            case WM_MOUSEMOVE: msg = "WM_MOUSEMOVE"; return 1;
            case WM_MOUSEWHEEL: msg = "WM_MOUSEWHEEL"; break;
            case WM_MOUSEHWHEEL: msg = "WM_MOUSEHWHEEL"; break;
            case WM_RBUTTONDOWN: msg = "WM_RBUTTONDOWN"; break;
            case WM_RBUTTONUP: msg = "WM_RBUTTONUP"; break;
            default: 
                sprintf_s(msg_buff, "Unknown msg: %u", wParam); 
                msg = msg_buff;
                break;
        }
        switch (wParam)
        {
            case WM_LBUTTONDOWN: msg = "WM_LBUTTONDOWN"; break;
            default: 
                sprintf_s(msg_buff, "Unknown msg: %u", wParam); 
                msg = msg_buff;
                break;
        }

        cout<<endl<<"Mouse: "<<msg<<endl;
    }
    
    return CallNextHookEx(NULL, code, wParam, lParam); 
}


LRESULT CALLBACK LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam) 
{
    static const DWORD key_c = 0x43;

    if (nCode == HC_ACTION) 
    {
        PKBDLLHOOKSTRUCT p = (PKBDLLHOOKSTRUCT)lParam;     
        DWORD Keystroke    = p->vkCode;
        switch (wParam) 
        {
            case WM_LBUTTONDOWN:
            case WM_LBUTTONUP: 
            case WM_MOUSEMOVE: 
            case WM_MOUSEWHEEL:
            case WM_MOUSEHWHEEL:
            case WM_RBUTTONDOWN:
            case WM_RBUTTONUP: 
            case WM_MBUTTONDOWN:        
            case WM_MBUTTONUP:                
                cout<<endl<<"mouse...: "<<wParam<<endl;
                break; 
            case WM_KEYDOWN:  
            {
                switch(Keystroke) {
                    case key_c: 
                        if( isKeyDown(VK_CONTROL) || isKeyDown(VK_LCONTROL) || isKeyDown(VK_RCONTROL) ) {
                           cout<<endl<<"Exiting process..."<<endl<<endl; 

                           cout<<endl<<"Close winds: "<<(closeWindows( wnd_info("MaskLayerClass1") )==EXIT_SUCCESS)<<endl;

                           return 0;
                           HWND maskWnd = FindWindow(L"MaskLayerClass" , L"MaskLayer");
                           SendMessage(maskWnd,  WM_CLOSE, 0, 0);

                           return 1;
                           //ExitProcess(EXIT_SUCCESS);
                        }

                        break;  
                    default:
                    {}
                }          
            }
            case WM_SYSKEYDOWN:
            {
                switch(Keystroke) {
                    case VK_F4:
                        cout<<endl<<"ALT+F4 blocked!"<<endl;
                        break;
                    default:
                    {}
                }
            }
            case WM_KEYUP:    
            case WM_SYSKEYUP: 
            default:
            {}
        }
    }

    return CallNextHookEx(NULL, nCode, wParam, lParam); 
} 

BOOL isClassWndLast(HWND hwnd)
{
    wnd_info Wnd(hwnd);
    GetClassName(Wnd.hwnd, Wnd.wClassName, Wnd.cNameSizeMax);
    wnd_search is_last(Wnd.wClassName);

    if( (  IsWindow(Wnd.hwnd) && is_last.getExtractedSize() == 1) || 
        ( !IsWindow(Wnd.hwnd) && is_last.getExtractedSize() == 0)  ) 
            return TRUE;   
    
    return FALSE;
}


LRESULT CALLBACK WndProc1(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
     switch (message)
     {
        case WM_DESTROY: {
            if( isClassWndLast(hwnd) ) 
                    PostQuitMessage(0);
            return 0;       
        }  
        case WM_CLOSE:
            break;
        case WM_CREATE: 
            break;
        case WM_LBUTTONDOWN:
            cout<<endl<<"windproc1"<<endl;
            break;
        case WM_KEYDOWN:
            break; 
     }

     return DefWindowProc(hwnd, message, wParam, lParam) ;
}

LRESULT CALLBACK WndProc2(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
     switch (message)
     {
        case WM_DESTROY: {
            if( isClassWndLast(hwnd) )
                PostQuitMessage(0);
            return 0;       
        }       
        case WM_CLOSE:
            break;
        case WM_CREATE: 
            break;
        case WM_LBUTTONDOWN:
            cout<<endl<<"windproc2"<<endl;
            break;
        case WM_KEYDOWN:
            break; 
     }

     return DefWindowProc(hwnd, message, wParam, lParam) ;
}

UINT bringConsoleForeground()
{
    HWND hConsole = GetConsoleWindow();

    if( hConsole != GetForegroundWindow() ) {

        SetForegroundWindow(hConsole);
        while( hConsole != GetForegroundWindow() ) {
            DWORD lockTimeOut    = 0;
            DWORD lockTimeOutNew = 0;
            DWORD dwThisTID      = GetCurrentThreadId();
            DWORD dwCurrTID      = GetWindowThreadProcessId(GetForegroundWindow(), NULL);
     
            AttachThreadInput(dwThisTID, dwCurrTID, TRUE);
     
            SystemParametersInfo(SPI_GETFOREGROUNDLOCKTIMEOUT, 0, &lockTimeOut, 0);
            SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT, 0, &lockTimeOutNew, SPIF_SENDWININICHANGE | SPIF_UPDATEINIFILE);
     
            AllowSetForegroundWindow(ASFW_ANY);
            SetForegroundWindow(hConsole);
     
            SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT, 0, &lockTimeOut, SPIF_SENDWININICHANGE | SPIF_UPDATEINIFILE);
            AttachThreadInput(dwThisTID, dwCurrTID, FALSE);
        }
    }

    if( hConsole == GetForegroundWindow() )
        return EXIT_SUCCESS;

    return EXIT_FAILURE;
}


UINT bringWindowForeground(const HWND hwnd)
{
    if( hwnd != GetForegroundWindow() ) {

        SetForegroundWindow(hwnd);
        while( hwnd != GetForegroundWindow() ) {
            DWORD lockTimeOut    = 0;
            DWORD lockTimeOutNew = 0;
            DWORD dwThisTID      = GetCurrentThreadId();
            DWORD dwCurrTID      = GetWindowThreadProcessId(GetForegroundWindow(), NULL);
     
            AttachThreadInput(dwThisTID, dwCurrTID, TRUE);
     
            SystemParametersInfo(SPI_GETFOREGROUNDLOCKTIMEOUT, 0, &lockTimeOut, 0);
            SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT, 0, &lockTimeOutNew, SPIF_SENDWININICHANGE | SPIF_UPDATEINIFILE);
     
            AllowSetForegroundWindow(ASFW_ANY);
            SetForegroundWindow(hwnd);
     
            SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT, 0, &lockTimeOut, SPIF_SENDWININICHANGE | SPIF_UPDATEINIFILE);
            AttachThreadInput(dwThisTID, dwCurrTID, FALSE);
        }
    } 

    if( hwnd == GetForegroundWindow() )
        return EXIT_SUCCESS;

    return EXIT_FAILURE;
}

LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
     //cout<<endl<<"Callback msg: "<<message<<" : "<<wParam<<" : "<<lParam<<endl;
     switch (message)
     {
        case WM_DESTROY:
            PostQuitMessage(0); 
            return 0;         
        case WM_CLOSE:
            break;
        case WM_CREATE: 
            //ShowCursor(false);
            break;
        case WM_SETCURSOR:
            break;
        case WM_PAINT:
            break;
        case WM_KILLFOCUS:
            break;
        case WM_LBUTTONDOWN:
            break;
        case WM_TIMER:
            switch(wParam) {               
                case IDT_TIMER2: 
                    bringConsoleForeground();
                    bringWindowForeground(hwnd);    

                    break;                
            }
            
            break;
     }

     return DefWindowProc(hwnd, message, wParam, lParam) ;
}



DWORD WINAPI watingInterr(LPVOID lpParam) 
{ 
    
    Sleep(100);
    HINSTANCE hinstExe = GetModuleHandle(NULL);  

    WNDCLASSEX  wc;
    wc.cbSize        = sizeof(WNDCLASSEX);
    wc.style         = 0;
    wc.lpfnWndProc   = WndProc1;
    wc.cbClsExtra    = 0;
    wc.cbWndExtra    = 0;
    wc.hInstance     = hinstExe;
    wc.hIcon         = LoadIcon(NULL, IDI_APPLICATION);
    wc.hCursor       = LoadCursor(NULL, IDC_HAND);
    wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
    wc.lpszMenuName  = NULL;
    wc.lpszClassName = L"MaskLayerClass1";
    wc.hIconSm       = LoadIcon(NULL, IDI_APPLICATION);
    RegisterClassEx(&wc);
    

    HWND hwnd = CreateWindowEx(
                            NULL,
                            L"MaskLayerClass1",
                            L"MaskLayer1",
                            WS_VISIBLE,
                            0, 
                            0, 
                            110, 110,
                            0, 
                            NULL, 
                            hinstExe, 
                            NULL
                         );
   
    HWND hwnd1 = CreateWindowEx(
                            NULL,
                            L"MaskLayerClass1",
                            L"MaskLayer2",
                            WS_VISIBLE,
                            200, 
                            200, 
                            110, 110,
                            0, 
                            NULL, 
                            hinstExe, 
                            NULL
                         );

   CreateWindowEx(
              NULL,
              L"MaskLayerClass1",
              L"MaskLayer3",
              WS_VISIBLE,
              200, 
              200, 
              110, 110,
              0, 
              NULL, 
              hinstExe, 
              NULL
           );

   CreateWindowEx(
              NULL,
              L"MaskLayerClass1",
              L"MaskLayer4",
              WS_VISIBLE,
              200, 
              200, 
              110, 110,
              0, 
              NULL, 
              hinstExe, 
              NULL
           );

   CreateWindowEx(
              NULL,
              L"MaskLayerClass1",
              L"MaskLayer5",
              WS_VISIBLE,
              200, 
              200, 
              110, 110,
              0, 
              NULL, 
              hinstExe, 
              NULL
           );

   CreateWindowEx(
                            NULL,
                            L"MaskLayerClass1",
                            L"MaskLayer6",
                            WS_VISIBLE,
                            200, 
                            200, 
                            110, 110,
                            0, 
                            NULL, 
                            hinstExe, 
                            NULL
                         );
    
    SetWindowLong(hwnd,  GWL_WNDPROC, (LONG)WndProc1);
    SetWindowLong(hwnd1, GWL_WNDPROC, (LONG)WndProc2);

    HWND hh = FindWindow(L"MaskLayerClass" , L"MaskLayer");
    cout<<endl<<"hwndm: "<<hh<<endl;
    cout<<endl<<"hwnd: "<<hwnd<<endl;
    cout<<endl<<"hwnd1: "<<hwnd1<<endl;

    test();

    MSG message = {0};     
    while (GetMessage(&message,NULL,0,0)) {      
        TranslateMessage( &message );         
        DispatchMessage ( &message );   
    } 
    
    //cout<<endl<<"msg_end1: "<<message.message<<endl; 
            OUTSTREAM<<"msg_end1: "<<message.message<<endl;
            PRINTOUT;                              
    while( 1 );
    Sleep(2000); 

    return EXIT_SUCCESS;
}





DWORD WINAPI disableFullscreen(LPVOID lpParam) 
{
    DWORD FullscreenMode = FALSE;

    HINSTANCE hinstExe = GetModuleHandle(NULL);
    cout<<endl<<"hinst: "+to_string((_Longlong)hinstExe)<<endl;       
    HHOOK hhkLowLevelKybd  = SetWindowsHookEx(WH_KEYBOARD_LL, LowLevelKeyboardProc, hinstExe, 0);
    //HHOOK hhkLowLevelMouse = SetWindowsHookEx(WH_MOUSE_LL, LowLevelKeyboardProc, hinstExe, 0);

    WNDCLASSEX  wc;
    wc.cbSize        = sizeof(WNDCLASSEX);
    wc.style         = 0;
    wc.lpfnWndProc   = WndProc;
    wc.cbClsExtra    = 0;
    wc.cbWndExtra    = 0;
    wc.hInstance     = hinstExe;
    wc.hIcon         = LoadIcon(NULL, IDI_APPLICATION);
    wc.hCursor       = LoadCursor(NULL, IDC_WAIT);
    wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
    wc.lpszMenuName  = NULL;
    wc.lpszClassName = L"MaskLayerClass";
    wc.hIconSm       = LoadIcon(NULL, IDI_APPLICATION);

    RegisterClassEx(&wc);
    
    HWND hwnd = CreateWindowEx(
                            WS_EX_LAYERED,
                            L"MaskLayerClass",
                            L"MaskLayer",
                            WS_POPUP|WS_VISIBLE|WS_MAXIMIZE,
                            0, 
                            0, 
                            0, 0,
                            0, 
                            NULL, 
                            hinstExe, 
                            NULL
                         );

        //ShowWindow(hwnd, v);
        //UpdateWindow(hwnd);

        SetLayeredWindowAttributes(hwnd,0, 100, LWA_ALPHA); 
        UINT TimerId = SetTimer(hwnd, IDT_TIMER1, 1, (TIMERPROC)NULL);      

    cout<<endl<<"hwndm: "<<hwnd<<endl;

    MSG message = {0};     
    while (GetMessage(&message,NULL,0,0)) {      
        TranslateMessage( &message );         
        DispatchMessage ( &message );          
    } 

    cout<<endl<<"msg_end: "<<message.message<<endl;

    KillTimer(hwnd, IDT_TIMER1);

    HWND hConsole = GetConsoleWindow();
    if( hConsole != GetForegroundWindow() )
        SetForegroundWindow(hConsole);

    UnhookWindowsHookEx(hhkLowLevelKybd);
    //UnhookWindowsHookEx(hhkLowLevelMouse);
    
    return EXIT_SUCCESS;
}


int main(int argc, char *argv[])
{
    HANDLE pipeIn    = NULL;
    HANDLE pipeOut   = NULL;
    HANDLE hThread1  = NULL;
    HANDLE hThread2  = NULL;
    DWORD  hThreadID = 0;
    const int diplayTextSize = 1000;
    char displayTextBuffer[diplayTextSize+1] = {0};
    const char *defaultDisplayText = "TeSt...";


    for(int i=0; i<argc; ++i)
        if( !strncmp(argv[i], "-i", 2) )
            pipeIn  = (HANDLE)atoi(argv[i+1]);
        else if( !strncmp(argv[i], "-o", 2) )
            pipeOut = (HANDLE)atoi(argv[i+1]);

    if(argv[argc] == NULL) cout<<"NULL"<<endl;
    else cout<<"last *argv not a NULL!"<<endl;


    cout<<"argc = "<<argc<<endl;
    for(int i=0; i<argc; ++i) 
        cout<<"par"<<i<<" = "<<argv[i]<<endl;
    cout<<"IN: " <<(int)pipeIn <<endl;
    cout<<"OUT: "<<(int)pipeOut<<endl;


    if(pipeIn) {
        DWORD bytesRead = 0;
        memset(displayTextBuffer, 0, strlen(defaultDisplayText));
        ReadFile(pipeIn, displayTextBuffer, diplayTextSize, &bytesRead, 0); 
        //WriteFile(out, input.c_str(), input.size(), &bytesRead, 0); 
    }
    else
        strncpy_s(displayTextBuffer, defaultDisplayText, strlen(defaultDisplayText));
    
    
    HANDLE hEvent = CreateEvent( NULL, FALSE, FALSE, TEXT("hEvent") );     
           
    hThread1 = CreateThread(
               NULL,
               0,
               watingInterr,
               NULL,
               0,
               &hThreadID
               );

    hThread2 = CreateThread(
               NULL,
               0,
               disableFullscreen,
               NULL,
               0,
               &hThreadID
               );

               
           
    while(1){
      
        if( WAIT_OBJECT_0 == WaitForSingleObject(hThread1, 0) )
            break; 
        else {
                   
            //cout<<displayTextBuffer<<endl;
            static int i = 0;
            //OUTSTREAM<<++i<<") "<<displayTextBuffer<<endl;
            //PRINTOUT;
        }

        Sleep(1000);   
    }

#if WIN_OS
        system("cls");
#elif UNIX
        system("clear");
#endif
    //ShowWindow(tray, SW_SHOW);
    cout<<"Logging in...";
    Sleep(2000);

    return EXIT_SUCCESS;
}
